package main;
import javazoom.jl.player.Player;
import java.io.*;
import enums.RationLevel;
import enums.TravelPace;
import error_checking.PurchaseInputChecker;
import error_checking.StoreStockChecker;
import gui.EndScreenM5Panel;
import gui.EndScreenM6Panel;
import gui.FileChooserPanel;
import gui.ImageChooser;
import gui.LandmarkPanel;
import gui.PartyCreationPanel;
import gui.RiverPanel;
import gui.StorePanel;
import gui.TitleScreenPanel;
import gui.TrailPanel;
import gui.TravelOptionsPanel;

import java.applet.AudioClip;
import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Display {

	public static final int TITLE_SCREEN_PANEL = 0;
	public static final int PARTY_CREATION_PANEL = 1;
	public static final int TRAVEL_OPTIONS_PANEL = 2;
	public static final int M5_END_SCREEN = 3;
  //public static final int ???????_PANEL = 4;
	public static final int LANDMARK_PANEL = 5;
	public static final int STORE_PANEL = 6;
	public static final int M6_END_SCREEN = 7;
	public static final int TRAIL_PANEL = 8;
	public static final int WIN_PANEL = 9;
	public static final int RIVER_PANEL = 10;
	public static final int FILE_CHOOSER_PANEL = 11;
	public static final int LOSE_PANEL = 12;
	
	private Menu menu;
	
	private int prev_panel = 1;
	/**
	 * @return the prev_panel
	 */
	public int getPrev_panel() {
		return prev_panel;
	}

	/**
	 * @param prev_panel the prev_panel to set
	 */
	public void setPrev_panel(int prev_panel) {
		this.prev_panel = prev_panel;
	}

	/**
	 * @return the cur_panel
	 */
	public int getCur_panel() {
		return cur_panel;
	}

	/**
	 * @param cur_panel the cur_panel to set
	 */
	public void setCur_panel(int cur_panel) {
		this.cur_panel = cur_panel;
	}

	private int cur_panel = 1;
	
	private JPanel panel_M_Main;

	//each panel object
	private TitleScreenPanel titleScreenPanel;
	private PartyCreationPanel partyCreationPanel;
	private TravelOptionsPanel travelOptionsPanel;
	private EndScreenM5Panel M5EndScreen;
	private EndScreenM6Panel M6EndScreen;
	private StorePanel storePanel;
	private TrailPanel trailPanel;
	private LandmarkPanel landmarkPanel;
	private RiverPanel riverPanel;
	private FileChooserPanel fileChooserPanel;
	
	private JFrame frame;

	private JPanel panelWin;
	private JPanel panelLose;
	private JLabel lblWinMessage;
	private JLabel lblLoseMessage;
	
	private ImageChooser riverImageChooser;
	private ImageChooser landmarkImageChooser;

	/**
	 * switches the GUI to a different menu
	 * 
	 * @param newPanel
	 *            the menu being changed to.
	 * 
	 *             0) Title Screen 
	 *             1) Party Creation 
	 *             2) Travel Options 
	 *             3) End Screen
	 *            10) River Panel 
	 */
	public void switchMainPanel(int newPanel) {
		if(newPanel >= TITLE_SCREEN_PANEL && newPanel <= LOSE_PANEL){
			prev_panel = cur_panel;
			
			if (newPanel == LANDMARK_PANEL) {
				WorldState state = menu.getWorldstate();
				Location loc = state.getCurrentLocation();
				int distLeft = menu.getWorldstate().getTravelGroup().calculateTravelPace();
				
				
				//middleware esque fix for glitch with stores
				if(loc instanceof Trail) {
					Trail t = (Trail) loc;
					if(distLeft > (t.getDistance()-t.getProgress())) {
						loc = t.getNextLandmark();
					}
				}
				
				Landmark locL;
				landmarkPanel.getBtnGoToStore().setVisible(false);
				if (loc instanceof Landmark) {
					locL = (Landmark) loc;
					if (locL.getStore() != null) {
						landmarkPanel.getBtnGoToStore().setVisible(true);
					}
				}
			}
			
			cur_panel = newPanel;
			menu.setPanelSave(cur_panel);
			System.out.println("Current panel is: "+menu.getPanelSave());
			CardLayout cl_panel_M_Main = (CardLayout) panel_M_Main.getLayout();
			cl_panel_M_Main.show(panel_M_Main, newPanel + "");
		}
	}

	/**
	 * @return the panel_M_Main
	 */
	public JPanel getPanel_M_Main() {
		return panel_M_Main;
	}

	/**
	 * @param panel_M_Main the panel_M_Main to set
	 */
	public void setPanel_M_Main(JPanel panel_M_Main) {
		this.panel_M_Main = panel_M_Main;
	}

	/**
	 * Returns the Ration Level (enum) selected by the user on the Travel
	 * Options page.
	 * 
	 * @return the new Ration Level
	 */
	private RationLevel getRationsSelection() {
		return travelOptionsPanel.getRationsSelection();
	}

	/**
	 * Returns the Travel Pace (enum) selected by the user on the Travel Options
	 * page.
	 * 
	 * @return the new Travel Pace
	 */
	private TravelPace getTravelSelection() {
		return travelOptionsPanel.getTravelSelection();
	}

	/**
	 * shows the travel group info on the first End screen text pane
	 * 
	 * called when travel options continue button is clicked
	 */
	private void showTravelGroupInfo() {
		M5EndScreen.setTravelGroupPane(menu.getTravelGroupString());
	}
	private void save() {
		System.out.println("You clicked the save button");
		try { 
			menu.setPanelSave(cur_panel);
			System.out.println("Current Panel you're saving is "+menu.getPanelSave());

			Date date = new Date();
			DateFormat dateFormat = new SimpleDateFormat("MM-dd-yy_HH-mm-ss");
			String d = dateFormat.format(date);
			String filename = "OregonTrail_"+d+".ot";
			FileOutputStream fos = new FileOutputStream(filename); 
			ObjectOutputStream oos = new ObjectOutputStream(fos); 
			oos.writeObject(menu); 
			oos.flush(); 
			oos.close(); 
			fos.flush();
			fos.close();
			JOptionPane.showMessageDialog(frame,
					"The current game state has been saved in the file "+filename, "Save Successful",
					JOptionPane.INFORMATION_MESSAGE);
		} catch(Exception ex) { 
				ex.printStackTrace();
		} 
		System.out.println("Finished saving!");
	}
	/**
	 * puts the appropriate values in the store GUI panel components
	 */
	private void setupStore() {
		// Set up all of the components on the store panel with the right
		// names/quantities/prices
		NumberFormat nf = NumberFormat.getCurrencyInstance();
		WorldState state = menu.getWorldstate();
		Landmark loc = (Landmark) state.getCurrentLocation();
		Store store = loc.getStore();
		TravelGroup group = state.getTravelGroup();
		int[] quantities = group.getPack().getQuantity();

		storePanel.getLblStorePrice1().setText(nf.format(store.getPriceOxen()));
		storePanel.getLblStorePrice2().setText(nf.format(store.getPriceFood()));
		storePanel.getLblStorePrice3().setText(nf.format(store.getPriceClothes()));
		storePanel.getLblStorePrice4().setText(nf.format(store.getPriceWagonWheel()));
		storePanel.getLblStorePrice5().setText(nf.format(store.getPriceWagonAxle()));
		storePanel.getLblStorePrice6().setText(nf.format(store.getPriceWagonTongue()));
		storePanel.getLblStoreQty1().setText("" + store.getQtyOxen() + "/" + quantities[0]);
		storePanel.getLblStoreQty2().setText("" + store.getQtyFood() + "/" + quantities[1]);
		storePanel.getLblStoreQty3().setText("" + store.getQtyClothes() + "/" + quantities[2]);
		storePanel.getLblStoreQty4().setText("" + store.getQtyWagonWheel() + "/" + quantities[3]);
		storePanel.getLblStoreQty5().setText("" + store.getQtyWagonAxle() + "/" + quantities[4]);
		storePanel.getLblStoreQty6().setText("" + store.getQtyWagonTongue() + "/" + quantities[5]);
		storePanel.getLblStoreWeight1().setText("" + store.WEIGHTS[0] + " lbs");
		storePanel.getLblStoreWeight2().setText("" + store.WEIGHTS[1] + " lbs");
		storePanel.getLblStoreWeight3().setText("" + store.WEIGHTS[2] + " lbs");
		storePanel.getLblStoreWeight4().setText("" + store.WEIGHTS[3] + " lbs");
		storePanel.getLblStoreWeight5().setText("" + store.WEIGHTS[4] + " lbs");
		storePanel.getLblStoreWeight6().setText("" + store.WEIGHTS[5] + " lbs");

		// Also set the store name, the label for that is: lblStoreName
		storePanel.getLblStoreName().setText("Welcome to WagonTrails Store");
		storePanel.getLblPlayerMoney().setText("Total Weight: "
				+ group.getPack().getTotalWeight() + "lbs");
		storePanel.getLblPlayerMoney().setText("Money: " + nf.format(group.getMoney()));
		storePanel.getLblStoreName().setText(loc.getName() +" General Store");
	}
	public void updateHealth() {
		TravelGroup group = menu.getWorldstate().getTravelGroup();
		Pioneer[] names = group.getParty();
		trailPanel.getLblPlayerHealth().setText(names[0].getName()+" "+names[0].getHealthStr());
		trailPanel.getLblChar1Health().setText(names[1].getName()+" "+names[1].getHealthStr());
		trailPanel.getLblChar2Health().setText(names[2].getName()+" "+names[2].getHealthStr());
		trailPanel.getLblChar3Health().setText(names[3].getName()+" "+names[3].getHealthStr());
		trailPanel.getLblChar4Health().setText(names[4].getName()+" "+names[4].getHealthStr());
		
		landmarkPanel.getLblPlayerHealth().setText(names[0].getName()+" "+names[0].getHealthStr());
		landmarkPanel.getLblCharacter1Health().setText(names[1].getName()+" "+names[1].getHealthStr());
		landmarkPanel.getLblCharacter2Health().setText(names[2].getName()+" "+names[2].getHealthStr());
		landmarkPanel.getLblCharacter3Health().setText(names[3].getName()+" "+names[3].getHealthStr());
		landmarkPanel.getLblCharacter4Health().setText(names[4].getName()+" "+names[4].getHealthStr());
		
	}

	/**
	 * This method is called when the purchase button is clicked from the store
	 * panel
	 * 
	 * It buys items from the store and puts them in the player's inventory
	 * 
	 * Error Checking: -It should check if the user entered actual numbers for
	 * the purchase quantities -It should check if the user has enough money to
	 * make the purchase -It should check if the wagon can hold the weight of
	 * the new purchases -It should check if the store has the item in stock
	 * 
	 */
	private void handlePurchase() {
		
		PurchaseInputChecker inputChecker;
		StoreStockChecker stockChecker;
		
		/*
		 * to let you know when this method is called when you are running the
		 * GUI
		 */
		WorldState state = menu.getWorldstate();
		Landmark loc = (Landmark) state.getCurrentLocation();
		Store store = loc.getStore();
		TravelGroup group = state.getTravelGroup();

		// Have dialogue boxes pop up for all the errors that can happen if you
		// try to purchase something

		// Checks for invalid input
		String[] purchaseAmounts = {storePanel.getTxtPurchaseAmount1().getText(), 
									storePanel.getTxtPurchaseAmount2().getText(),
									storePanel.getTxtPurchaseAmount3().getText(),
									storePanel.getTxtPurchaseAmount4().getText(),
									storePanel.getTxtPurchaseAmount5().getText(),
									storePanel.getTxtPurchaseAmount6().getText()};
		
		inputChecker = new PurchaseInputChecker(purchaseAmounts);
		if(inputChecker.hasError()){
			JOptionPane.showMessageDialog(frame, inputChecker.getErrorText(),
					"Error", JOptionPane.ERROR_MESSAGE);
			return;
		}
		
		// puts a 0 in for no purchase amount entry
		int oxen = 0;
		if (!storePanel.getTxtPurchaseAmount1().getText().equals("")) {
			oxen = Integer.parseInt(storePanel.getTxtPurchaseAmount1().getText());
		}
		int food = 0;
		if (!storePanel.getTxtPurchaseAmount2().getText().equals("")) {
			food = Integer.parseInt(storePanel.getTxtPurchaseAmount2().getText());
		}
		int clothing = 0;
		if (!storePanel.getTxtPurchaseAmount3().getText().equals("")) {
			clothing = Integer.parseInt(storePanel.getTxtPurchaseAmount3().getText());
		}
		int wheels = 0;
		if (!storePanel.getTxtPurchaseAmount4().getText().equals("")) {
			wheels = Integer.parseInt(storePanel.getTxtPurchaseAmount4().getText());
		}
		int axles = 0;
		if (!storePanel.getTxtPurchaseAmount5().getText().equals("")) {
			axles = Integer.parseInt(storePanel.getTxtPurchaseAmount5().getText());
		}
		int tongues = 0;
		if (!storePanel.getTxtPurchaseAmount6().getText().equals("")) {
			tongues = Integer.parseInt(storePanel.getTxtPurchaseAmount6().getText());
		}
		
		// store stock checker
		int[] storeQtys = {	store.getQtyOxen(), store.getQtyFood(),
							store.getQtyClothes(), store.getQtyWagonAxle(),
							store.getQtyWagonWheel(), store.getQtyWagonTongue()};
		int[] purchaseQtys = {oxen, food, clothing, axles, wheels, tongues};
				
		stockChecker = new StoreStockChecker(storeQtys, purchaseQtys);
		if(stockChecker.hasError()){
			JOptionPane.showMessageDialog(frame, stockChecker.getErrorText(),
					"Error", JOptionPane.ERROR_MESSAGE);
			return;
		}

		// Checks if the purchase would give them too much weight
		Inventory testWeight = new Inventory();
		testWeight.setQtyOxen(group.getPack().getQtyOxen() + oxen);
		testWeight.setQtyFood(group.getPack().getQtyFood() + food);
		testWeight.setQtyClothes(group.getPack().getQtyClothes() + clothing);
		testWeight.setQtyWagonAxle(group.getPack().getQtyWagonAxle() + axles);
		testWeight
				.setQtyWagonWheel(group.getPack().getQtyWagonWheel() + wheels);
		testWeight.setQtyWagonTongue(group.getPack().getQtyWagonTongue()
				+ tongues);
		if (testWeight.getTotalWeight() > store.MAX_WEIGHT) {
			JOptionPane.showMessageDialog(frame,
					"Your wagon will weigh too much if you buy that!", "Error",
					JOptionPane.ERROR_MESSAGE);
			return;
		}
		
		// Checks if the user has enough money to make a purchase
		double total = oxen * store.getPriceOxen() + food
				* store.getPriceFood() + clothing * store.getPriceClothes()
				+ axles * store.getPriceWagonAxle() + wheels
				* store.getPriceWagonWheel() + tongues
				* store.getPriceWagonTongue();
		// Checks if the user bought anything
		if (total == 0.0) {
			JOptionPane.showMessageDialog(frame, "You didn't buy anything",
					"Error", JOptionPane.ERROR_MESSAGE);
			return;
		} else if (total > group.getMoney()) {
			JOptionPane.showMessageDialog(frame,
					"You don't have enough money for that :(", "Error",
					JOptionPane.ERROR_MESSAGE);
			return;
		} else {
			double beforeMoney = group.getMoney();
			int beforeWeight = group.getPack().getTotalWeight();
			int[] quantities = group.getPack().getQuantity();
			// Actually buys from the store
			store.buyFromStore(Inventory.OXEN_ID, oxen, group);
			store.buyFromStore(Inventory.FOOD_ID, food, group);
			store.buyFromStore(Inventory.CLOTHES_ID, clothing, group);
			store.buyFromStore(Inventory.WAGON_WHEEL_ID, wheels, group);
			store.buyFromStore(Inventory.WAGON_AXLE_ID, axles, group);
			store.buyFromStore(Inventory.WAGON_TONGUE_ID, tongues, group);

			// updates store fields
			storePanel.getLblPlayerWagonWeight().setText("Total Weight: "
					+ group.getPack().getTotalWeight() + "lbs / "
					+ group.getPack().MAX_WEIGHT + "lbs");
			NumberFormat nf = NumberFormat.getCurrencyInstance();
			storePanel.getLblPlayerMoney().setText("Money: $" + nf.format(group.getMoney()));

			double changeInMoney = beforeMoney - group.getMoney();
			int changeInWeight = group.getPack().getTotalWeight()
					- beforeWeight;
			JOptionPane.showMessageDialog(frame, "You just spent "
					+ nf.format(changeInMoney) + ".\nNow your wagon has added "
					+ changeInWeight + "lbs.", "Alert",
					JOptionPane.INFORMATION_MESSAGE);

			storePanel.getLblStoreQty1().setText("" + store.getQtyOxen() + "/" + quantities[0]);
			storePanel.getLblStoreQty2().setText("" + store.getQtyFood() + "/" + quantities[1]);
			storePanel.getLblStoreQty3().setText("" + store.getQtyClothes() + "/" + quantities[2]);
			storePanel.getLblStoreQty4().setText("" + store.getQtyWagonWheel() + "/" + quantities[3]);
			storePanel.getLblStoreQty5().setText("" + store.getQtyWagonAxle() + "/" + quantities[4]);
			storePanel.getLblStoreQty6().setText("" + store.getQtyWagonTongue() + "/" + quantities[5]);

			trailPanel.getLblRemainingFood().setText("Remaining food "
					+ group.getPack().getQtyFood());

			storePanel.getTxtPurchaseAmount1().setText("");
			storePanel.getTxtPurchaseAmount2().setText("");
			storePanel.getTxtPurchaseAmount3().setText("");
			storePanel.getTxtPurchaseAmount4().setText("");
			storePanel.getTxtPurchaseAmount5().setText("");
			storePanel.getTxtPurchaseAmount6().setText("");

			return;
		}
		// TODO: if you make multiple purchases the store's item quantity should
		// update
	}

	/**
	 * Takes in a string and determines whether or not it is made up of numbers
	 * 
	 * @param str
	 *            the string
	 * @return whether or not its made of numbers
	 */
	private boolean isNumStr(String str) {
		if (str.equals(""))
			return true;
		for (int i = 0; i < str.length(); i++) {
			if (!(str.charAt(i) >= '0' && str.charAt(i) <= '9')) {
				return false;
			}
		}
		if (str.length() == 0)
			return false;
		return true;
	}

	/**
	 * shows the player's inventory
	 * 
	 * called when leave store button is clicked
	 */
	private void showPlayerInventoryInfo() {

		// Call the appropriate toString methods to show (copy pasted from M6
		// Wiki):
		// Players cash is reduced by purchase amount .......... 15
		// Player cannot purchase item if not enough money ... 10
		// Weight of purchase is deducted from the wagon ..... 10
		// Maximum weight of wagon is enforced somehow ..... 10
		// Purchases are added to the player's inventory ........ 10

		// GUI component you are working with (and it's set text method)
		// txtpnStoreString.setText(whatever.toString here);

		WorldState state = menu.getWorldstate();
		TravelGroup group = state.getTravelGroup();

		// for an example look at showTravelGroupInfo()
		storePanel.getLblPlayerWagonWeight().setText("Total Weight: "
				+ group.getPack().getTotalWeight() + "lbs / "
				+ group.getPack().MAX_WEIGHT + "lbs");
		storePanel.getLblPlayerMoney().setText("Money: $" + group.getMoney());
	}

	/**
	 * Handles all the operations that need to happen when the travel group
	 * travels for a day -update travel pace -update rations -update the day
	 * -update the distance traveled -update the total distance traveled -change
	 * the fields on the trail panel to reflect the updated values -random event
	 * generation
	 */
	private void travel() {
		// TODO implement travel pace update, date update, total distance
		// traveled update, rations update
		WorldState state = menu.getWorldstate();
		TravelGroup group = state.getTravelGroup();
		Inventory pack = group.getPack();

		// Make sure the group can travel...
		// CHECKS FOR REASONS THE GROUP CANT TRAVEL

		// Not enough food

		int numDead = 0;
		for(Pioneer p: group.getParty()){
			if(p.getHealth()==Health.DEAD) numDead++;
		}
		if(numDead==5){
			JOptionPane.showMessageDialog(frame,
					"Everyone in your party is dead!",
					"Error", JOptionPane.ERROR_MESSAGE);
			switchMainPanel(LOSE_PANEL);
		}
		
		if(pack.getQtyFood() < 0)
			pack.setQtyFood(0);

		if (pack.getQtyFood()
				- (group.getRationLevel().getRations()) < 0) {
			JOptionPane.showMessageDialog(frame,
					"Cant continue at current ration level, not enough food!",
					"Error", JOptionPane.ERROR_MESSAGE);
			// we could also just set to starving here...

			// No Oxen
		} else if (group.getPack().getQtyOxen() <= 0
				&& group.getTravelPace() != TravelPace.STOPPED) {
			JOptionPane.showMessageDialog(frame,
					"You cant move, you don't own any Oxen!", "Error",
					JOptionPane.ERROR_MESSAGE);

			// If the group is ok to travel...
		} else {
			int foodLeft = 0;
			randomEvent();
			Location loc = state.getCurrentLocation();
			Trail trail;
			if (!(loc instanceof Landmark)) {
				trail = (Trail) loc;
			} else {
				Landmark land = (Landmark) loc;
				trail = land.getNext();
			}
			Landmark nextL = trail.getNextLandmark();
			// //System.out.println(trail.getDistance()+" "+trail.getProgress()+" "+group.getTravelPace().getPace());
			if ((trail.getDistance() - trail.getProgress() - group
					.getTravelPace().getPace()) <= 0) {

				if(nextL.getName() == null){
					//lblLandmarkTitle.setText("Welcome to " + nextL.getName());
					switchMainPanel(WIN_PANEL);
				} else {
					//jarvis broke this
					String welcomeBlurb = "Welcome to " + nextL.getName();
					if(nextL instanceof River) {
						riverPanel.getLblRiverTitle().setText(welcomeBlurb);
						switchRiverImage();
						setRiverInfo();
						switchMainPanel(RIVER_PANEL);
					} else {
						landmarkPanel.getLblLandmarkTitle().setText(welcomeBlurb);
						switchLandmarkImage();
						switchMainPanel(LANDMARK_PANEL);
					}
				}
				// state.updateWorldState();
				/*
				 * if(!(loc instanceof Landmark)) { trail = (Trail) loc; } else{
				 * Landmark land = (Landmark)loc; trail = land.getNext(); }
				 */
				// nextL = trail.getNextLandmark();
				// distLeft = trail.getDistance()-trail.getProgress();
				// foodLeft = pack.getQtyFood();
				// lblRemainingFood.setText("Remaining food "+foodLeft);
				// lblDate.setText("Date: "+state.getDate());
				// lblMilesToGo.setText(distLeft+" miles to reach "+nextL.getName());
			}
			state.updateWorldState();
			int distLeft = trail.getDistance() - trail.getProgress();
			foodLeft = pack.getQtyFood();
			trailPanel.getLblRemainingFood().setText("Remaining food " + foodLeft);
			trailPanel.getLblDate().setText("Date: " + state.getDate());
			trailPanel.getLblMilesToGo().setText(distLeft + " miles to reach "
					+ nextL.getName());
			//trailPanel.getLblDate().setText("Total Distance Traveled: "
			//		+ state.getTotalDistanceTraveled());
			trailPanel.getLblTotalDistance().setText("Total Distance Traveled: "+state.getTotalDistanceTraveled());

		}
	}

	public void updateTrailText() {
		WorldState state = menu.getWorldstate();
		TravelGroup group = state.getTravelGroup();
		Inventory pack = group.getPack();

		Location loc = state.getCurrentLocation();
		
		Trail trail;
		if (!(loc instanceof Landmark)) {
			trail = (Trail) loc;
		} else {
			Landmark land = (Landmark) loc;
			String welcomeBlurb = "Welcome to " + land.getName();
			landmarkPanel.getLblLandmarkTitle().setText(welcomeBlurb);

			trail = land.getNext();
		}
		Landmark nextL = trail.getNextLandmark();
		
		switchLandmarkImage();
		int distLeft = trail.getDistance() - trail.getProgress();
		int foodLeft = pack.getQtyFood();
		trailPanel.getLblRemainingFood().setText("Remaining food " + foodLeft);
		trailPanel.getLblDate().setText("Date: " + state.getDate());
		trailPanel.getLblMilesToGo().setText(distLeft + " miles to reach "
				+ nextL.getName());
		trailPanel.getLblTotalDistance().setText("Total Distance Traveled: "+state.getTotalDistanceTraveled());

		updateHealth();
		NumberFormat nf = NumberFormat.getCurrencyInstance();
		trailPanel.getLblMoney().setText("Money: "+nf.format(menu.getWorldstate().getTravelGroup().getMoney()));

	}
	
	/**
	 * Initializes the image choosers with the appropriate panel components and image filepaths
	 */
	private void initImageChoosers(){
		String[] lfilepaths = {"src/Landmark-IndependenceMissouri.jpg", 
				"src/Landmark-FtKerney.jpg", "src/Landmark-ChimneyRock.jpg",
				"src/Landmark-FtLaramie.jpg", "src/Landmark-IndependenceRock.jpg",
				"src/Landmark-SouthPass.jpg", "src/Landmark-FtBridger.jpg",
				"src/Landmark-SodaSprings.jpg", "src/Landmark-FtHall.jpg",
				"src/Landmark-FtBoise.jpg","src/Landmark-BlueMountains.jpg",
				"src/Landmark-FtWallaWalla.jpg", "src/Landmark-Dalles.jpg"};
		String[] rfilepaths = {"src/River-KansasRiver.jpg", "src/River-BigBlue.jpg",
				"src/River-SnakeRiver.jpg"};
		
		landmarkImageChooser = new ImageChooser(lfilepaths, landmarkPanel.getPanelImage());
		riverImageChooser = new ImageChooser(rfilepaths, riverPanel.getPanelImage());
		
		landmarkImageChooser.displayImage(0);
		riverImageChooser.displayImage(0);
		
	}
	
	/**
	 * updates the landmark image for the current landmark
	 */
	private void switchLandmarkImage(){	//416, 262
		WorldState state = menu.getWorldstate();
		Location loc = state.getCurrentLocation();
		Trail trail;
		Landmark land = null;
		if(loc instanceof Trail) {
			trail = (Trail)state.getCurrentLocation();
			land = trail.getNextLandmark();
		} else if(loc instanceof Landmark) {
			land = (Landmark)loc;
		}
		landmarkImageChooser.displayImage(0);	
		if(land == null) return;
		if(land.getName().equals("Independence, Missouri")){
			landmarkImageChooser.displayImage(0);	
		}if(land.getName().equals("Ft Kearny")){
			landmarkImageChooser.displayImage(1);	
		}if(land.getName().equals("Chimney Rock")){
			landmarkImageChooser.displayImage(2);	
		}if(land.getName().equals("Fort Laramie")){
			landmarkImageChooser.displayImage(3);	
		}if(land.getName().equals("Independence Rock")){
			landmarkImageChooser.displayImage(4);	
		}if(land.getName().equals("South Pass")){
			landmarkImageChooser.displayImage(5);	
		}if(land.getName().equals("Fort Bridger")){
			landmarkImageChooser.displayImage(6);	
		}if(land.getName().equals("Soda Springs")){
			landmarkImageChooser.displayImage(7);	
		}if(land.getName().equals("Fort Hall")){
			landmarkImageChooser.displayImage(8);	
		}if(land.getName().equals("Fort Boise")){
			landmarkImageChooser.displayImage(9);	
		}if(land.getName().equals("Blue Mountains")){
			landmarkImageChooser.displayImage(10);	
		}if(land.getName().equals("Fort Walla Walla")){
			landmarkImageChooser.displayImage(11);	
		}if(land.getName().equals("Dalles")){
			landmarkImageChooser.displayImage(12);	
		}
	}
	
	/**
	 * updates the river image for the current river
	 */
	private void switchRiverImage(){ //658, 185
		WorldState state = menu.getWorldstate();
		Trail loc = (Trail)state.getCurrentLocation();
		Landmark land = loc.getNextLandmark();
		riverImageChooser.displayImage(1);
		if(land.getName().equals("Kansas River")){
			riverImageChooser.displayImage(0);
		}if(land.getName().equals("Big Blue")){
			riverImageChooser.displayImage(1);
		}if(land.getName().equals("Snake River Crossing")){
			riverImageChooser.displayImage(2);
		}
	}
	
	private void setRiverInfo(){
		WorldState state = menu.getWorldstate();
		Trail loc = (Trail)state.getCurrentLocation();
		River river = (River)loc.getNextLandmark();
		riverPanel.getLblRiverDepth().setText("River Depth: " + river.getWaterLevel());
		riverPanel.getLblRiverWidth().setText("River Width: " + river.getWaterWidth());
	}
	
	private void randomEvent() {
		WorldState state = menu.getWorldstate();
		Random rand = new Random();
		int chance = rand.nextInt(100)+1;
		System.out.println("you roll: "+chance);
		if(chance < 20) {
			int playerChance = rand.nextInt(5);
			Pioneer[] p = state.getTravelGroup().getParty();
			String[] randomEvents = new String[10];
			randomEvents[0] = p[playerChance].getName()+" just had a terrible accident - one of your oxen ran them over and they died.";
			randomEvents[1] = "Uh oh... "+p[2].getName()+" and "+p[3].getName()+" are arguing again... this won't be a fun trip if they keep this up.";
			randomEvents[2] = "Your wagon wheel broke! Luckily, you repaired it. But you lost a day of travel time!";
			randomEvents[3] = "You and your wagon mates almost had a nasty run-in with a buffalo herd - but you survived!";
			randomEvents[4] = "A wild bandit ambushed you and stole all of your food supplies!";
			randomEvents[5] = "Despite the rough conditions of the trail, your wagon mates are having a great time! Good job keeping morale up!";
			randomEvents[6] = p[playerChance].getName()+" has dysentary!";
			randomEvents[7] = "Spooky... you just passed by a destroyed wagon and the skeletons of five travellers...";
			randomEvents[8] = "Hooray! A passing traveller donated 10lbs of food to your group!";
			randomEvents[9] = "You managed to get lost and 3 days have passed!";
			if(chance >= 10) chance-=10;
			if(chance==0){
				p[playerChance].setAlive(false);
				p[playerChance].setHealth(Health.DEAD);
			}
			else if(chance==2){
				state.advanceDay();
			}
			else if(chance == 4){
				int food = state.getTravelGroup().getPack().getQtyFood();
				if(food > 0){
					food += state.getTravelGroup().getRationLevel().getRations();
					state.getTravelGroup().getPack().setQtyFood(0);
				}
			}
			else if(chance == 6){
				p[playerChance].setHealth(Health.DYSENTARY);
			}
			else if(chance == 8){
				int food = state.getTravelGroup().getPack().getQtyFood();
				state.getTravelGroup().getPack().setQtyFood(food+10);
			}
			else if(chance == 9){
				for(int i = 0; i < 3; i++) state.advanceDay();
			}

			JOptionPane.showMessageDialog(frame,
					randomEvents[chance], "Oh Dear!",
					JOptionPane.INFORMATION_MESSAGE);
		}

	}
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {

		//look and feel stuff
		try {
	        UIManager.setLookAndFeel(
	            UIManager.getSystemLookAndFeelClassName());
	    } 
	    catch (UnsupportedLookAndFeelException e) {
	       // handle exception
	    }
	    catch (ClassNotFoundException e) {
	       // handle exception
	    }
	    catch (InstantiationException e) {
	       // handle exception
	    }
	    catch (IllegalAccessException e) {
	       // handle exception
	    }

		
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Display window = new Display();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public Display() {
		menu = new Menu();
		initialize();
		switchMainPanel(TITLE_SCREEN_PANEL);
	}

	/**
	 * Initialize the contents of the frame.
	 */
	public void initialize() {	
		
		
		prev_panel = 1;
		cur_panel = 1;
		frame = new JFrame("Wagon Trails");
		frame.setBounds(100, 100, 720, 480);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);

		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		panel_M_Main = new JPanel();
		panel_M_Main.setBounds(0, 0, 704, 442);
		frame.getContentPane().add(panel_M_Main);
		panel_M_Main.setLayout(new CardLayout(0, 0));

		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		titleScreenPanel = new TitleScreenPanel();
		panel_M_Main.add(titleScreenPanel, "0"); // Title Screen Panel -- panel
													// 0
		
		titleScreenPanel.getBtnLoad().addMouseListener(
				new MouseAdapter() {
					@Override
					public void mousePressed(MouseEvent arg0) {
						switchMainPanel(FILE_CHOOSER_PANEL);
					}
				});
		
		// switch from the TitleScreen to the Party Creation Panel
		titleScreenPanel.getContinueButton().addMouseListener(
				new MouseAdapter() {
					@Override
					public void mousePressed(MouseEvent arg0) {
						switchMainPanel(PARTY_CREATION_PANEL);
					}
				});

		titleScreenPanel.getM6Button().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				//
				travelOptionsPanel.setOnTrail(true);
				
				Profession prof = Profession.BANKER;
				ArrayList<String> names = new ArrayList<String>(4);
				names.add("Nick Barrash");
				names.add("Jarvis Johnson");
				names.add("Ira Kaplan");
				names.add("Ramya Ramakrishnan");
				menu.startUpMenu("Naomi Robert", names, prof,
						getTravelSelection(), getRationsSelection());
				showTravelGroupInfo();
				// System.out.println(menu.getTravelGroupString());

				WorldState state = menu.getWorldstate();
				Landmark loc = (Landmark) state.getCurrentLocation();
				Store store = loc.getStore();
				TravelGroup group = state.getTravelGroup();
				double beforeMoney = group.getMoney();
				int beforeWeight = group.getPack().getTotalWeight();

				storePanel.getLblPlayerWagonWeight().setText("Total Weight: "
						+ group.getPack().getTotalWeight() + "lbs / "
						+ group.getPack().MAX_WEIGHT + "lbs");
				storePanel.getLblPlayerMoney().setText("Money: $" + group.getMoney());

				double changeInMoney = beforeMoney - group.getMoney();
				int changeInWeight = group.getPack().getTotalWeight()
						- beforeWeight;

				int[] quantities = group.getPack().getQuantity();
				
				storePanel.getLblStoreQty1().setText("" + store.getQtyOxen() + "/" + quantities[0]);
				storePanel.getLblStoreQty2().setText("" + store.getQtyFood() + "/" + quantities[1]);
				storePanel.getLblStoreQty3().setText("" + store.getQtyClothes() + "/" + quantities[2]);
				storePanel.getLblStoreQty4().setText("" + store.getQtyWagonWheel() + "/" + quantities[3]);
				storePanel.getLblStoreQty5().setText("" + store.getQtyWagonAxle() + "/" + quantities[4]);
				storePanel.getLblStoreQty6().setText("" + store.getQtyWagonTongue() + "/" + quantities[5]);


				storePanel.getLblStoreWeight1().setText("" + store.WEIGHTS[0] + " lbs");
				storePanel.getLblStoreWeight2().setText("" + store.WEIGHTS[1] + " lbs");
				storePanel.getLblStoreWeight3().setText("" + store.WEIGHTS[2] + " lbs");
				storePanel.getLblStoreWeight4().setText("" + store.WEIGHTS[3] + " lbs");
				storePanel.getLblStoreWeight5().setText("" + store.WEIGHTS[4] + " lbs");
				storePanel.getLblStoreWeight6().setText("" + store.WEIGHTS[5] + " lbs");

				storePanel.getLblStorePrice1().setText("$" + store.getPriceOxen());
				storePanel.getLblStorePrice2().setText("$" + store.getPriceFood());
				storePanel.getLblStorePrice3().setText("$" + store.getPriceClothes());
				storePanel.getLblStorePrice4().setText("$" + store.getPriceWagonWheel());
				storePanel.getLblStorePrice5().setText("$" + store.getPriceWagonAxle());
				storePanel.getLblStorePrice6().setText("$" + store.getPriceWagonTongue());

				trailPanel.getLblRemainingFood().setText("Remaining food "
						+ group.getPack().getQtyFood());

				storePanel.getLblStoreName().setText(loc.getName() +" General Store");
				
				switchMainPanel(STORE_PANEL);
			}
		});

		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		partyCreationPanel = new PartyCreationPanel();
		panel_M_Main.add(partyCreationPanel, "1");

		// ------------------ Continue Button on Party Creation mouse listener
		// ------------------
		partyCreationPanel.btnBack.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				switchMainPanel(TITLE_SCREEN_PANEL);	
			}
		});
		
		//Profession help text updater
		partyCreationPanel.comboBox_PC_Profession.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(arg0.getActionCommand().equals("comboBoxChanged")){
					if (partyCreationPanel.comboBox_PC_Profession
							.getSelectedIndex() == 0) {
						partyCreationPanel.lblProfessionInfo.setText("Bankers start with $500");
					} else if (partyCreationPanel.comboBox_PC_Profession
							.getSelectedIndex() == 1) {
						partyCreationPanel.lblProfessionInfo.setText("Carpenters start with $300");
					} else if (partyCreationPanel.comboBox_PC_Profession
							.getSelectedIndex() == 2) {
						partyCreationPanel.lblProfessionInfo.setText("Farmers start with $200");
					}
				}
			}
		});
		
		partyCreationPanel.button_PC_Continue
				.addMouseListener(new MouseAdapter() {
					@Override
					public void mousePressed(MouseEvent arg0) {
						if (!(partyCreationPanel.textField_PC_PlayerName
								.getText().length() >= 1)) {
							JOptionPane.showMessageDialog(frame,
									"Player must have a name.", "Error",
									JOptionPane.ERROR_MESSAGE);
							return;
						}
						if (!(partyCreationPanel.textField_PC_Name1.getText()
								.length() >= 1)) {
							JOptionPane.showMessageDialog(frame,
									"Person 1 must have a name.", "Error",
									JOptionPane.ERROR_MESSAGE);
							return;
						}
						if (!(partyCreationPanel.textField_PC_Name2.getText()
								.length() >= 1)) {
							JOptionPane.showMessageDialog(frame,
									"Person 2 must have a name.", "Error",
									JOptionPane.ERROR_MESSAGE);
							return;
						}
						if (!(partyCreationPanel.textField_PC_Name3.getText()
								.length() >= 1)) {
							JOptionPane.showMessageDialog(frame,
									"Person 3 must have a name.", "Error",
									JOptionPane.ERROR_MESSAGE);
							return;
						}
						if (!(partyCreationPanel.textField_PC_Name4.getText()
								.length() >= 1)) {
							JOptionPane.showMessageDialog(frame,
									"Person 4 must have a name.", "Error",
									JOptionPane.ERROR_MESSAGE);
							return;
						}
						switchMainPanel(TRAVEL_OPTIONS_PANEL);
					}
				});

		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		travelOptionsPanel = new TravelOptionsPanel();
		panel_M_Main.add(travelOptionsPanel, "2"); // Travel Options Panel
		// -- panel 2
		travelOptionsPanel.setLayout(null);

		travelOptionsPanel.getBackButton().addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent arg0) {
				switchMainPanel(PARTY_CREATION_PANEL);
			}
		});
		
		// ------------------ Continue Button on Travel Options mouse listener
		// ------------------
		travelOptionsPanel.getContinueButton().addMouseListener(new MouseAdapter() {

			/**
			 * -Switches to the End Screen panel -Gets the pioneer names from
			 * the Party Creation panel and puts them into an array -Calls
			 * startUpMenu
			 * 
			 * @param arg0
			 *            when the mouse is pressed on the continue button
			 */
			@Override
			public void mousePressed(MouseEvent arg0) {
				// When the travel options panel comes up during
				// character creation at the very start
				if (!travelOptionsPanel.isOnTrail()) {
					boolean checkNames;
					Profession prof = Profession.NONE;
					ArrayList<String> names = new ArrayList<String>(4);
					names.add(partyCreationPanel.textField_PC_Name1.getText());
					names.add(partyCreationPanel.textField_PC_Name2.getText());
					names.add(partyCreationPanel.textField_PC_Name3.getText());
					names.add(partyCreationPanel.textField_PC_Name4.getText());
					if (partyCreationPanel.comboBox_PC_Profession
							.getSelectedIndex() == 0) {
						prof = Profession.BANKER;
					} else if (partyCreationPanel.comboBox_PC_Profession
							.getSelectedIndex() == 1) {
						prof = Profession.CARPENTER;
					} else if (partyCreationPanel.comboBox_PC_Profession
							.getSelectedIndex() == 2) {
						prof = Profession.FARMER;
					}
					menu.startUpMenu(partyCreationPanel.textField_PC_PlayerName
							.getText(), names, prof, getTravelSelection(),
							getRationsSelection());
					showTravelGroupInfo();
					travelOptionsPanel.getBackButton().setVisible(false);
					setupStore();
					switchMainPanel(STORE_PANEL);
					

					// When the travel options panel comes up from
					// the user clicking travel options out on the trail
					// Everything is already initialized, things just need
					// to set
				} else {
					WorldState state = menu.getWorldstate();
					TravelGroup group = state.getTravelGroup();
					group.setRationLevel(getRationsSelection());
					group.setTravelPace(getTravelSelection());
					switchMainPanel(prev_panel);
				}
				updateHealth();
			}
		});

		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		M5EndScreen = new EndScreenM5Panel();
		panel_M_Main.add(M5EndScreen, "3");
		M5EndScreen.setLayout(null);

		M5EndScreen.getContinueButton().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				
			}
		});

		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		landmarkPanel = new LandmarkPanel();
		panel_M_Main.add(landmarkPanel, "5");
		landmarkPanel.setLayout(null);
		
		//go to store button
		landmarkPanel.getBtnGoToStore().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				if (landmarkPanel.getBtnGoToStore().isVisible()) {
					switchMainPanel(STORE_PANEL);
					setupStore();
				}
			}
		});

		//save button
		landmarkPanel.getBtnSave().addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				save();
			}
		});
			
		//TODO: Player Health stuff
		//Just set to "" or remove the components from the GUI panel if you don't want to use them.
		landmarkPanel.getLblPlayerHealth().setText("Player health here");
		landmarkPanel.getLblCharacter1Health().setText("1st character health here");
		landmarkPanel.getLblCharacter2Health().setText("2nd character health here");
		landmarkPanel.getLblCharacter3Health().setText("3rd character health here");
		landmarkPanel.getLblCharacter4Health().setText("4th character health here");
		
		//change travel options button
		landmarkPanel.getBtnTravelOptions().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				switchMainPanel(TRAVEL_OPTIONS_PANEL);
				travelOptionsPanel.setOnTrail(true);
			}
		});
		
		//go to trail button
		landmarkPanel.getBtnGoOnTrail().addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				int foodLeft = 0;
				WorldState state = menu.getWorldstate();
				Location loc = state.getCurrentLocation();
				Trail trail;
				if (!(loc instanceof Landmark)) {
					trail = (Trail) loc;
				} else {
					Landmark land = (Landmark) loc;
					trail = land.getNext();
				}
				Landmark nextL = trail.getNextLandmark();
				int distLeft = trail.getDistance() - trail.getProgress();
				TravelGroup group = state.getTravelGroup();
				Inventory pack = group.getPack();
				foodLeft = pack.getQtyFood();
				trailPanel.getLblRemainingFood().setText("Remaining food " + foodLeft);
				trailPanel.getLblDate().setText("Date: " + state.getDate());
				trailPanel.getLblMilesToGo().setText(distLeft + " miles to reach "
						+ nextL.getName());
				state.updateWorldState();
				if(nextL.getName()==null)
					switchMainPanel(WIN_PANEL);
				else {
					NumberFormat nf = NumberFormat.getCurrencyInstance();
					trailPanel.getLblMoney().setText("Money: "+nf.format(menu.getWorldstate().getTravelGroup().getMoney()));
					switchMainPanel(TRAIL_PANEL);
				
				}
			}
		});
		
		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		storePanel = new StorePanel();
		panel_M_Main.add(storePanel, "6");
		storePanel.setLayout(null);
		
		/* funky code ninja, bet you didn't know you could do this ;P */
		
//		ActionListener txtList = new ActionListener() {
//			public void actionPerformed(ActionEvent e) {
//				WorldState state = menu.getWorldstate();
//				TravelGroup group = state.getTravelGroup();
//				int tempWeight = group.getPack().getTotalWeight();
//				
//				/* TODO fix this */
//				
//				storePanel.getLblPlayerWagonWeight().setText("Total Weight: "
//						+ tempWeight + "lbs / "
//						+ group.getPack().MAX_WEIGHT + "lbs");
//				storePanel.getLblPlayerMoney().setText("Money: $" + group.getMoney());
//			}
//		};
//		
//		storePanel.getTxtPurchaseAmount1().addActionListener(txtList);
//		storePanel.getTxtPurchaseAmount2().addActionListener(txtList);
//		storePanel.getTxtPurchaseAmount3().addActionListener(txtList);
//		storePanel.getTxtPurchaseAmount4().addActionListener(txtList);
//		storePanel.getTxtPurchaseAmount5().addActionListener(txtList);
	
		
		storePanel.getPurchaseButton().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				handlePurchase();
			}
		});

		storePanel.getLeaveButton().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				WorldState state = menu.getWorldstate();
				TravelGroup group = state.getTravelGroup();
				if (group.getPack().getQtyOxen() <= 0) {
					JOptionPane.showMessageDialog(frame,
							"You need to buy oxen to pull your wagon.",
							"Error", JOptionPane.ERROR_MESSAGE);
				} else {
					showPlayerInventoryInfo();
					M6EndScreen.getTxtpnStoreString().setText(menu.updateDisplay());
					storePanel.setFirstStore(false);
					storePanel.getLblHelpText().setVisible(false);
					updateHealth();
					switchMainPanel(LANDMARK_PANEL);
				}
			}
		});

		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		M6EndScreen = new EndScreenM6Panel();
		panel_M_Main.add(M6EndScreen, "7");
		M6EndScreen.setLayout(null);

		M6EndScreen.getBtnM6EndContinue().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				updateHealth();
				switchMainPanel(LANDMARK_PANEL);
			}
		});

		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////
		
		WorldState state = menu.getWorldstate();
		Landmark loc = (Landmark) state.getCurrentLocation();
		Trail trail = loc.getNext();
		Landmark nextL = trail.getNextLandmark();
		int distLeft = trail.getDistance() - trail.getProgress();
		TravelGroup group = state.getTravelGroup();

		trailPanel = new TrailPanel();
		panel_M_Main.add(trailPanel, "8");
		trailPanel.setLayout(null);

		trailPanel.getLblRemainingFood().setText("Remaining food "
				+ group.getPack().getQtyFood());

		/**
		 * When the Travel Options button is pressed, go to travel options
		 */
		trailPanel.getBtnTravelOptions().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				switchMainPanel(TRAVEL_OPTIONS_PANEL);
				travelOptionsPanel.setOnTrail(true);
			}
		});
		
		trailPanel.getBtnSave().addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				save();
			}
		});

		/**
		 * When the Travel button is pressed, the group travels for a day
		 */
		trailPanel.getBtnTravel().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				
				travel();
				updateHealth();
				
			}
		});
		
		//save button
		landmarkPanel.getBtnSave().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				save();
				//TODO: save button logic (on a trail)
			}
		});
		
		//TODO: update character health. Here are all of the GUI objects for that.
		//Just set to "" or remove the components from the GUI panel if you don't want to use them.
		trailPanel.getLblPlayerHealth().setText("Player health here");
		trailPanel.getLblChar1Health().setText("1st character health here");
		trailPanel.getLblChar2Health().setText("2nd character health here");
		trailPanel.getLblChar3Health().setText("3rd character health here");
		trailPanel.getLblChar4Health().setText("4th character health here");

		trailPanel.getLblMilesToGo().setText(distLeft + " miles to reach "
				+ nextL.getName());

		trailPanel.getLblTotalDistance().setText("Total Distance Traveled: "
				+ state.getTotalDistanceTraveled());
		
		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////		
		panelWin = new JPanel();
		panel_M_Main.add(panelWin, "9");
		panelWin.setLayout(null);
		
		lblWinMessage = new JLabel("You made it to Oregon!");
		lblWinMessage.setHorizontalAlignment(SwingConstants.CENTER);
		lblWinMessage.setFont(new Font("Tahoma", Font.PLAIN, 25));
		lblWinMessage.setBounds(169, 191, 360, 77);
		panelWin.add(lblWinMessage);
		
		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////		
		panelLose = new JPanel();
		panel_M_Main.add(panelLose, "12");
		panelLose.setLayout(null);
		
		lblLoseMessage = new JLabel("Game Over :(");
		lblLoseMessage.setHorizontalAlignment(SwingConstants.CENTER);
		lblLoseMessage.setFont(new Font("Tahoma", Font.PLAIN, 25));
		lblLoseMessage.setBounds(169, 191, 360, 77);
		panelLose.add(lblLoseMessage);
		
		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////	
		riverPanel = new RiverPanel();
		panel_M_Main.add(riverPanel, "10");
		riverPanel.setLayout(null);
		
		/**
		 * FORD THE RIVER
		 */
		riverPanel.getBtnFord().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				Random rand = new Random();
				if(rand.nextInt(7) > 2) {
					JOptionPane.showMessageDialog(frame,
							"You managed to ford, whatever that means", "information",
							JOptionPane.INFORMATION_MESSAGE);
				
					
				} else {
					JOptionPane.showMessageDialog(frame,
							"You'd be so dead right now if it had been implemented", "Death!",
							JOptionPane.ERROR_MESSAGE);
				}
				
				travel();
				NumberFormat nf = NumberFormat.getCurrencyInstance();
				trailPanel.getLblMoney().setText("Money: "+nf.format(menu.getWorldstate().getTravelGroup().getMoney()));
				switchMainPanel(TRAIL_PANEL);
			}
		});
		
		/**
		 * CAULK ACROSS THE RIVER
		 */
		riverPanel.getBtnCaulk().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				Random rand = new Random();
				TravelGroup group = menu.getWorldstate().getTravelGroup();
				Inventory pack = group.getPack();
				
				if(rand.nextInt(7) > 2) {
					JOptionPane.showMessageDialog(frame,
							"You managed to caulk, whatever that means", "information",
							JOptionPane.INFORMATION_MESSAGE);
				
					
				} else {
					HashMap<Integer, String> ids = new HashMap<Integer, String>();
					String[] items = {"Oxen", "Food", "Clothes", "Wagon Axel", "Wagon Wheel", "Wagon Tongue"};
					for(int i=0; i < items.length; i++) ids.put(i, items[i]);
					
					int lossOne = rand.nextInt(5)+1;
					int lossTwo = rand.nextInt(5)+1;
					if(lossTwo == lossOne) {
						lossTwo = ((lossTwo + 1)%5);
					}
					
					int[] packArr = pack.getQuantity();
					
					double pctLoss = ((rand.nextInt(10)+1)/10.0);
					
					int[] lost = {(int) Math.ceil(packArr[lossOne]*pctLoss), (int) Math.ceil(packArr[lossTwo]*pctLoss) };
					
					packArr[lossOne]-= lost[0];
					packArr[lossTwo]-= lost[1];
					
					if(packArr[lossOne] < 0) packArr[lossOne] = 0;
					if(packArr[lossTwo] < 0) packArr[lossTwo] = 0;
					
					pack.setQuantity(packArr);
					String lossMessage = " Prepare to lose a lot of shit. Say goodbye to " 
					+ lost[0] + " units of "+ ids.get(lossOne)+ " and " + lost[1] + " units of "+ ids.get(lossTwo);
					if(pctLoss == 0.0) lossMessage = " But somehow you managed to avoid losing anything";
					JOptionPane.showMessageDialog(frame,
							"You dun' goofed." + lossMessage, "Oof!",
							JOptionPane.ERROR_MESSAGE);
				}
				
				travel();
				NumberFormat nf = NumberFormat.getCurrencyInstance();
				trailPanel.getLblMoney().setText("Money: "+nf.format(menu.getWorldstate().getTravelGroup().getMoney()));
				switchMainPanel(TRAIL_PANEL);
				
				
			}
		});
		
		/**
		 * FERRY ACROSS THE RIVER
		 */
		riverPanel.getBtnFerry().addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent arg0) {
				
				WorldState state = menu.getWorldstate();
				TravelGroup group = state.getTravelGroup();
				
				if(group.getMoney() >= riverPanel.getCost()) {
				
					
					group.setMoney(group.getMoney()-riverPanel.getCost());
					for(int i = 0; i < riverPanel.getWaitTime()-2; i++) state.advanceDay();
					
					JOptionPane.showMessageDialog(frame,
							"You pay "+riverPanel.costToString()+" and "+ riverPanel.getWaitTime()+" days have passed.", "information",
							JOptionPane.INFORMATION_MESSAGE);
					
					travel();
					NumberFormat nf = NumberFormat.getCurrencyInstance();
					trailPanel.getLblMoney().setText("Money: "+nf.format(menu.getWorldstate().getTravelGroup().getMoney()));
					switchMainPanel(TRAIL_PANEL);
				} else {
					JOptionPane.showMessageDialog(frame,
							"Due to insufficient funds, the Ferry is unavailable.", "Insufficient Funds!",
							JOptionPane.ERROR_MESSAGE);
				}

			}
		});
		
		//sets up the image choosers for landmark and river panels
		initImageChoosers();	
	
		// //////////////////////////////////////////////////////////////////////////////
		// //////////////////////////////////////////////////////////////////////////////		
		fileChooserPanel = new FileChooserPanel();
		panel_M_Main.add(fileChooserPanel, "11");
		fileChooserPanel.setLayout(null);
		
		fileChooserPanel.getFileChooser().addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				//if LOAD
				if(arg0.getActionCommand().equals("ApproveSelection")){
					String path = fileChooserPanel.getFileChooser().getSelectedFile().getAbsolutePath();
					System.out.println("The filepath you chose: " + path);
					try { 
						FileInputStream fis = new FileInputStream(path); 
						ObjectInputStream ois = new ObjectInputStream(fis); 
						menu = (Menu)ois.readObject(); 
						ois.close();
						fis.close();
						System.out.println("The menu had this panel: "+menu.getPanelSave());
						
					} catch(Exception e) { 
						JOptionPane.showMessageDialog(frame, e.getLocalizedMessage(),
								"Dear God!", JOptionPane.ERROR_MESSAGE);
					} 
					updateTrailText();
					
					switchMainPanel(menu.getPanelSave());
					
					//TODO: Load file logic +panel switching here
						//useful filechooser methods:
							//to get the chooser: fileChooserPanel.getFileChooser()
							//to get the selected file: fileChooserPanel.getFileChooser().getSelectedFile()
							//to get the selected file's filepath: fileChooserPanel.getFileChooser().getSelectedFile().getAbsolutePath() ^^^^used in println
				}
				//if CANCEL
				if(arg0.getActionCommand().equals("CancelSelection")){
					switchMainPanel(TITLE_SCREEN_PANEL);
				}
			}
			
		});
		
		Thread song_thread = new Thread() { 
		      public void run() {
		    	  try{
		  			FileInputStream fs = new FileInputStream("" +
		  					"src/oregonTrailSong.mp3");
		  			Player playMp3 = new Player(fs);
		  			playMp3.play();
		  		}
		  		catch(Exception e){
		  			System.out.println("Could not play :(");
		  		};
		      }
		    };
		song_thread.start();
		  }

}


